/*
 * debug.c
 *
 * the debug interface for HAL debug.
 *
 * Copyright (C) 2024 Sinh Micro, Inc.
 * Subject to the GNU Public License, version 2.
 *
 * Author: lixiang<lixiang@sinhmicro.com>
 * 
 * Encoding format: GB2312
 * Version: v1.2.2
 * Date: 2024-11-05
 */

#include "hal-config.h"
#include "hal-regs.h"

#include "types.h"
#include "system.h"
#include "uart.h"
#include "debug.h"

#if (CONFIG_USING_DEBUG > 0)
void debug_putc(char ch)
{
    uart0_putc(ch);
}

static void print_hex(uint16_t num);
static void print_dec(uint16_t num);

void debug_print(const char *format, int16_t number) {  
    const char *fmt_ptr = format;  
    while (*fmt_ptr) {  
        if (*fmt_ptr == '%') {  
            fmt_ptr++;  
            switch (*fmt_ptr) {  
                case 'x':  
                    print_hex(number);  
                    break;  
                case 'd':  
                    if (number < 0) {  
                        debug_putc('-');  
                        number = -number;  
                    }  
                    print_dec(number);  
                    break;  
                default:  
                    break;  
            }  
        } else if (*fmt_ptr == '\n') {  
            debug_putc('\r');
            debug_putc('\n');  
        } else {  
            debug_putc(*fmt_ptr);  
        }  
        fmt_ptr++;
    }  
}  

static uint16_t ex_10(uint8_t num)
{
	uint8_t i;
    uint16_t tmp = 1;

	for (i = 0; i < num; i++)
    	tmp = (tmp << 3) + (tmp << 1);  // * 10

    return tmp;     //tmp = 10^num
}

static void print_dec(uint16_t num)
{
    bool got_non_zero = false;

    uint8_t i;
    uint8_t tmp;
    uint16_t ex10_val;

    if (num == 0) {
        debug_putc('0');
        return;
    }

    i = 5;
    while (i) {
        i--;

        ex10_val = ex_10(i);

        tmp = num / ex10_val;
        num %= ex10_val;
        if (tmp == 0 && !got_non_zero)
            continue;

        got_non_zero = true;
		debug_putc(tmp + '0');
    }
}

static void print_hex(uint16_t num)
{
    bool got_non_zero = false;

    uint8_t i;
    uint8_t tmp;

    if (num == 0) {
        debug_putc('0');
        return;
    }

    i = 16;
    while (i) {
        i -= 4;
        tmp = (num >> i) & 0xf;

        if (tmp == 0 && !got_non_zero)
            continue;

        got_non_zero = true;
		if (tmp >= 10)
            debug_putc(tmp + 'a' - 10 );
        else
            debug_putc(tmp + '0');
    }
}

#endif

